package com.bungarus.busi;

import com.bungarus.Access;
import com.bungarus.event.AuthSucceededEvent;
import com.bungarus.event.SessionCreatedEvent;
import com.bungarus.model.Member;
import com.bungarus.model.MessageBuilder;
import com.bungarus.model.Session;
import com.bungarus.utils.IPAddressUtils;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.log4j.Logger;

/**
 *
 * Created by tang on 2018/11/11.
 */
@ChannelHandler.Sharable
public class CreateSessionHandler extends ChannelInboundHandlerAdapter {
    Logger logger = Logger.getLogger(CreateSessionHandler.class);
    private final Access access;

    public CreateSessionHandler(Access access) {
        this.access = access;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if(evt instanceof AuthSucceededEvent){
            AuthSucceededEvent event = (AuthSucceededEvent)evt;
            Member member = event.getMember();
            logger.debug("================ userEventTriggered: member is " + member.toString());

            String hostAddress = access.getHostAddress();
            logger.debug("Access host address ip in created session -> " + hostAddress);

            Session session = Session.newBuilder()
                    .id(ctx.channel().id())
                    .user(String.valueOf(member.getId()))
                    .app(event.getHeader().getApp())
                    .device(event.getHeader().getDev())
                    .tenant(member.getTenantId())
                    .ip(hostAddress)
                    .token(event.getHeader().getToken())
                    .port(Access.PORT_7800)
                    .build();

            //save the new session into memory
            Access.getSessionContainer().add(session, ctx.channel());
            //send the session info to nodes in transfer layer
            SessionCreatedEvent sessionCreatedEvent = new SessionCreatedEvent(session, event.getHeader());
            ctx.fireUserEventTriggered(sessionCreatedEvent);
        }
        else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if(cause instanceof AuthenticationInputException){
             ctx.writeAndFlush(MessageBuilder.buildAuthErrorMessage());
        }
        else if(cause instanceof BusiTimeoutException){
            ctx.writeAndFlush(MessageBuilder.buildTimeoutMessage());
        }
        else if(cause instanceof UserNonexistException){
            ctx.writeAndFlush(MessageBuilder.buildUserNonexistMessage());
        }
        else if(cause instanceof AuthenticationExpirationException){
            ctx.writeAndFlush(MessageBuilder.buildAuthExpirationMessage());
        }
    }
}
